"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**是否纯对象 */
const isPureObj = (o) => {
    const type = Object.prototype.toString.call(o);
    return type === "[object Object]";
};
/**判断数组是二维列表 */
const isList = (list) => list.every(isPureObj);
/**获取属性列表 */
const getKeys = (keys) => {
    if (!keys)
        return [];
    const ks = keys instanceof Array ? keys : keys.split(",");
    const mks = [...new Set(ks)].map((x) => x.replace(/^\s+/, ""));
    return mks.map((x) => x.replace(/\s+$/, "")).filter((x) => !!x);
};
/**获取字符串Unicode值总和 */
const getCode = (str) => {
    const arr = str.split("");
    const codes = arr.map((x, i) => str.charCodeAt(i));
    return codes.reduce((a, b) => a + b);
};
/**获取列比较器 */
const getComparator = (list, key = "") => {
    const cols = key ? list.map((x) => x[key]) : list;
    const types = cols.map((x) => typeof x);
    let asc, desc, ascM, descM;
    if (types.every((x) => x == "boolean")) {
        ascM = (a, b) => Number(a) - Number(b);
        descM = (a, b) => Number(b) - Number(a);
        asc = (a, b) => Number(a[key]) - Number(b[key]);
        desc = (a, b) => Number(b[key]) - Number(a[key]);
    }
    else if (types.every((x) => x == "number")) {
        ascM = (a, b) => a - b;
        descM = (a, b) => b - a;
        asc = (a, b) => a[key] - b[key];
        desc = (a, b) => b[key] - a[key];
    }
    else if (types.every((x) => x == "string")) {
        ascM = (a, b) => getCode(a) - getCode(b);
        descM = (a, b) => getCode(b) - getCode(a);
        asc = (a, b) => getCode(a[key]) - getCode(b[key]);
        desc = (a, b) => getCode(b[key]) - getCode(a[key]);
    }
    else {
        ascM = (a, b) => getCode(JSON.stringify(a)) - getCode(JSON.stringify(b));
        descM = (a, b) => getCode(JSON.stringify(b)) - getCode(JSON.stringify(a));
        asc = (a, b) => getCode(JSON.stringify(a[key])) - getCode(JSON.stringify(b[key]));
        desc = (a, b) => getCode(JSON.stringify(b[key])) - getCode(JSON.stringify(a[key]));
    }
    return { asc, desc, ascM, descM };
};
/**两端去空格 */
const trimStr = (str) => str.replace(/^\s+/, "").replace(/\s+$/, "");
/**两对象属性集是否相等 */
const isEqual = (x, y, keys) => {
    if (!isPureObj(x) || !isPureObj(y))
        return x == y;
    let ps = getKeys(keys);
    if (!ps.length)
        ps = Object.keys({ ...x, ...y });
    return ps
        .map((p) => ({ x: x[p] || p, y: y[p] || p }))
        .every((o) => o.x == o.y);
};
/**[数组、列表]按[多个]属性排序 */
Array.prototype.order = function (keys) {
    const list = this.slice(0);
    const ps = getKeys(keys);
    if (!isList(list)) {
        const c = getComparator(list);
        const [p, o] = ps[ps.length - 1].split(" ").map(trimStr);
        const fn = /^desc$/i.test(o || p) ? c.descM : c.ascM;
        return list.sort(fn);
    }
    for (let i = 0; i < ps.length; i++) {
        const [p, o] = ps[i].split(" ").map(trimStr);
        const c = getComparator(list, p);
        const fn = /^desc$/i.test(o) ? c.desc : c.asc;
        list.sort(fn);
    }
    return list;
};
/**[数组、列表]按[多个]属性分组 */
Array.prototype.group = function (keys) {
    const list = this;
    if (isList(list)) {
        const props = getKeys(keys);
        const gVals = list.map((x) => {
            const o = {};
            props.forEach((y) => (o[y] = x[y]));
            return o;
        });
        const groups = gVals.distinct(props);
        return groups.map((x) => {
            const info = x;
            const key = props.map((y) => `${x[y]}`).join("-");
            const items = list.filter((y) => isEqual(x, y, props)) || [];
            return { key, info, items };
        });
    }
    else {
        return list.map((x) => {
            const key = `${x}`;
            const info = x;
            const items = [x];
            return { key, info, items };
        });
    }
};
/**[数组、列表]按[多个]属性去重 */
Array.prototype.distinct = function (keys) {
    const list = this;
    const map = new Map();
    const ks = getKeys(keys);
    const getProp = (o) => {
        if (!ks.length || ks.length < 1)
            return JSON.stringify(o);
        return ks.map((x) => JSON.stringify(o[x] || x)).join("-");
    };
    if (!isList(list))
        return [...new Set(list)];
    return list.filter((x) => {
        const p = getProp(x);
        const has = map.has(p);
        return !has && map.set(p, x);
    });
};
/**[数组、列表]按[多个]属性获取并集 */
Array.prototype.union = function (list2, keys) {
    const list1 = this;
    const list = list1.concat(list2);
    return list.distinct(keys);
};
/**[数组、列表]按[多个]属性获取交集 */
Array.prototype.inter = function (list2, keys) {
    const list1 = this;
    //获取两列表的并集
    const list = list1.union(list2, keys);
    //并集中取两列表中都存在的
    return list.filter((x) => {
        const in1 = list1.some((y) => isEqual(x, y, keys));
        const in2 = list2.some((y) => isEqual(x, y, keys));
        return in1 && in2;
    });
};
/**[数组、列表]按[多个]属性获取差集 */
Array.prototype.differ = function (list2, keys) {
    const list1 = this;
    //获取两列表的并集
    const list = list1.union(list2, keys);
    //并集中取两列表中都存在的
    return list.filter((x) => {
        const in1 = list1.some((y) => isEqual(x, y, keys));
        const in2 = list2.some((y) => isEqual(x, y, keys));
        return (in1 && !in2) || (in2 && !in1);
    });
};
/**[数组、列表]获取(多个)属性重复的索引组 */
Array.prototype.getRepeatIndex = function (keys) {
    const list = this;
    const result = [];
    if (isList(list)) {
        const ks = getKeys(keys);
        const getProp = (o) => {
            if (!ks.length || ks.length < 1)
                return JSON.stringify(o);
            return ks.map((x) => JSON.stringify(o[x] || x)).join("-");
        };
        for (let i = 0; i < list.length; i++) {
            const item1 = list[i];
            for (let j = i + 1; j < list.length; j++) {
                const item2 = list[j];
                if (getProp(item1) == getProp(item2)) {
                    if (!result.some((x) => x == i))
                        result.push(i);
                    result.push(j);
                }
            }
        }
    }
    else {
        for (let i = 0; i < list.length; i++) {
            for (let j = i + 1; j < list.length; j++) {
                if (list[i] == list[j]) {
                    if (!result.some((x) => x == i))
                        result.push(i);
                    result.push(j);
                }
            }
        }
    }
    return result;
};
/**[数组、列表]获取(多个)属性重复的项目组 */
Array.prototype.getRepeat = function (keys) {
    const list = this;
    const indexs = this.getRepeatIndex(keys);
    return indexs.map((x) => list[x]);
};
/**[数组、列表]转换成索引访问器 */
Array.prototype.toRecord = function () {
    const list = this;
    const map = {};
    list.forEach((x, i) => (map[`${i}`] = x));
    return map;
};
/**[数组、列表]数据从索引访问器转换来 */
Array.fromRecord = function (record) {
    return Object.values(record);
};
/**[数组、列表]转换成索引访问器 */
Array.prototype.toMap = function () {
    const list = this;
    const map = new Map();
    list.forEach((x, i) => map.set(`${i}`, x));
    return map;
};
/**[数组、列表]清空数据 */
Array.prototype.clear = function () {
    while (this.length)
        this.pop();
};
/**[数组、列表]数据从索引访问器转换来 */
Array.fromMap = function (map) {
    const list = [];
    map.forEach((x) => list.push(x));
    return list;
};
/**指定长度创建数组 */
Array.create = function (len) {
    return new Array(len).fill("").map((x, i) => i + 1);
};
